using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.ProcessManagement;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ProcessManagements;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ProcessManagements
{
    /// <summary>
    /// 编辑工序 处理器
    /// </summary>
    public class UpdateProcessHandler : IRequestHandler<UpdateProcessCommand, APIResult<int>>
    {
        private readonly IBaseRepository<ProcessInfo> _processRepo;
        private readonly IBaseRepository<ProcessAttachment> _attachRepo;
        private readonly ILogger<UpdateProcessHandler> _logger;

        public UpdateProcessHandler(
            IBaseRepository<ProcessInfo> processRepo,
            IBaseRepository<ProcessAttachment> attachRepo,
            ILogger<UpdateProcessHandler> logger)
        {
            _processRepo = processRepo;
            _attachRepo = attachRepo;
            _logger = logger;
        }

        public Task<APIResult<int>> Handle(UpdateProcessCommand request, CancellationToken cancellationToken)
        {
            var res = new APIResult<int>();
            try
            {
                if (request.Id <= 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "无效的工序ID";
                    return Task.FromResult(res);
                }
                if (string.IsNullOrWhiteSpace(request.ProcessCode))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序编码不能为空";
                    return Task.FromResult(res);
                }
                if (string.IsNullOrWhiteSpace(request.ProcessName))
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序名称不能为空";
                    return Task.FromResult(res);
                }
                if (request.Status != 0 && request.Status != 1)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "状态只能是0(禁用)或1(启用)";
                    return Task.FromResult(res);
                }

                // 编码/名称唯一性（排除自身）
                var dupCode = _processRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ProcessInfo WHERE ProcessCode = @ProcessCode AND Id <> @Id AND IsDeleted = 0",
                    new { request.ProcessCode, request.Id });
                if (dupCode > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序编码已存在";
                    return Task.FromResult(res);
                }
                var dupName = _processRepo.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM ProcessInfo WHERE ProcessName = @ProcessName AND Id <> @Id AND IsDeleted = 0",
                    new { request.ProcessName, request.Id });
                if (dupName > 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "工序名称已存在";
                    return Task.FromResult(res);
                }

                using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);

                // 更新主表
                var updateSql = @"UPDATE ProcessInfo SET 
                                        ProcessCode=@ProcessCode,
                                        SystemCode=@SystemCode,
                                        ProcessName=@ProcessName,
                                        ClassificationId=@ClassificationId,
                                        ClassificationName=@ClassificationName,
                                        DepartmentId=@DepartmentId,
                                        DepartmentName=@DepartmentName,
                                        OwnerUserId=@OwnerUserId,
                                        OwnerUserName=@OwnerUserName,
                                        Status=@Status,
                                        Remark=@Remark
                                      WHERE Id=@Id AND IsDeleted=0";

                var now = DateTime.Now;
                var aff = _processRepo.Execute(updateSql, new
                {
                    request.ProcessCode,
                    request.SystemCode,
                    request.ProcessName,
                    request.ClassificationId,
                    request.ClassificationName,
                    request.DepartmentId,
                    request.DepartmentName,
                    request.OwnerUserId,
                    request.OwnerUserName,
                    request.Status,
                    request.Remark,
                    request.Id
                });

                if (aff <= 0)
                {
                    res.Code = APIEnums.Error;
                    res.Msg = "更新失败或记录不存在";
                    return Task.FromResult(res);
                }

                // 附件全量覆盖：先软删旧附件，再插入新附件
                var softDeleteAttachSql = "UPDATE ProcessAttachment SET IsDeleted=1 WHERE ProcessId=@ProcessId AND IsDeleted=0";
                _attachRepo.Execute(softDeleteAttachSql, new { ProcessId = request.Id });

                if (request.Attachments != null && request.Attachments.Count > 0)
                {
                    var insertAttachSql = @"INSERT INTO ProcessAttachment
                                                (ProcessId, FileName, FileUrl, FileSize, ContentType, FileHash, UploadTime, UploaderId, UploaderName, Status, Remark, CreateTime, CreateUser, IsDeleted)
                                              VALUES
                                                (@ProcessId, @FileName, @FileUrl, @FileSize, @ContentType, @FileHash, @UploadTime, @UploaderId, @UploaderName, @Status, @Remark, @CreateTime, @CreateUser, @IsDeleted);";

                    foreach (var a in request.Attachments)
                    {
                        _attachRepo.Execute(insertAttachSql, new
                        {
                            ProcessId = request.Id,
                            a.FileName,
                            a.FileUrl,
                            a.FileSize,
                            a.ContentType,
                            a.FileHash,
                            UploadTime = now,
                            UploaderId = (long?)null,
                            UploaderName = (string?)null,
                            a.Status,
                            a.Remark,
                            CreateTime = now,
                            CreateUser = "system",
                            IsDeleted = false
                        });
                    }
                }

                scope.Complete();

                res.Code = APIEnums.Success;
                res.Data = (int)request.Id;
                res.Msg = "更新成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新工序失败: {Message}", ex.Message);
                res.Code = APIEnums.Error;
                res.Msg = "更新工序异常";
                res.Data = 0;
            }

            return Task.FromResult(res);
        }
    }
}
